SWAGOLX.EXE (c) 1993 GDSOFT ALL RIGHTS RESERVED 00005 INTERRUPT HANDLING ROUTINES 1 05-28-9313:48ALL SWAG SUPPORT TEAM BITSTUFF.PAS IMPORT 40 {π Well Percy (or is it Kerry?), I see that the regular crowd here haveπ shown you how bit-level thingys work. So, I'll give you a workingπ example, including a Procedure to display the binary notation of anyπ Integer, so you can play With the inFormation they've given you. Theπ following Program reads & displays info from the equipment list Wordπ (Note: I've made [lazy] use of global Variables, do not emulate)...π}π(*******************************************************************)πProgram BitsNBytes; { ...or Digital Road Kill }πUsesπ Dos; { import Intr() and Registers }πVarπ NumberFDD, { number of floppy drives }π InitVMode, { intial video mode }π COMcount, { number of serial ports }π LPTcount : Byte; { number of Printer ports }π Is8087, { math copro installed? }π IsMouse, { pointing device installed? }π IsDMA, { DMA support installed? }π IsGame, { game port installed? }π IsModem : Boolean; { internal modem installed? }π EqWord : Word; { the equipment list Word }π Reg : Registers; { to access CPU Registers }π{-------------------------------------------------------------------}πFunction BitSet(AnyWord : Word; BitNum : Byte) : Boolean;π { return True if bit BitNum of AnyWord is 1, else False if it's 0 }πbeginπ BitSet := (BitNum in [0..15]) and ODD(AnyWord SHR BitNum);πend {BitSet};π{-------------------------------------------------------------------}πProcedure WriteBitWord( AnyWord : Word ); { show Word as binary }πVarπ BinString : String[16]; { represent binary bits }π MaxBit, { max number of bits }π BitNum : Byte; { bits 0..15 }πbeginπ BinString := '0000000000000000'; { default to 0 }π MaxBit := Length(BinString); { total bit count (16) }π For BitNum := 0 to PRED(MaxBit) do { process bits (0..15) }π if BitSet(AnyWord, BitNum) thenπ INC(BinString[MaxBit - BitNum]);π Write( BinString ); { Write the binary Form }πend {WriteBitWord};π{-------------------------------------------------------------------}πProcedure ProcessEquipList; { parse equipment list Word EqWord }πVarπ BitNum : Byte; { to check each bit }π EBitSet : Boolean; { True if a BitNum is 1, else False }πbeginπ For BitNum := 0 to 15 doπ begin { EqWord has 16 bits }π EBitSet := BitSet(EqWord,BitNum); { is this bit set? }π Case BitNum of { each bit has meaning }π 0 : if EBitSet then { if EqWord.0 is set }π NumberFDD := (EqWord SHR 6) and $3 + 1π elseπ NumberFDD := 0;π 1 : Is8087 := EBitSet; { if math co-pro found }π 2 : IsMouse := EBitSet; { if pointing device }π 3 : ; {reserved, do nothing}π 4 : InitVMode := (EqWord SHR BitNum) and $3;π 5..7 : ; {ignore}π 8 : IsDMA := EBitSet;π 9 : COMcount := (EqWord SHR BitNum) and $7;π 10,11 : ; {ignore}π 12 : IsGame := EBitSet;π 13 : IsModem := EBitSet;π 14 : LPTcount := (EqWord SHR BitNum) and $7;π 15 : ; {ignore}π end; {Case BitNum}π end; {For BitNum}πend {ProcessEquipList};π{-------------------------------------------------------------------}πFunction Maybe(Truth : Boolean) : String;πbeginπ if not Truth thenπ Maybe := ' not 'π elseπ Maybe := ' IS ';πend {Maybe};π{-------------------------------------------------------------------}πbeginπ Intr( $11, Reg );π EqWord := Reg.AX;π WriteLn;π Write('Equipment list Word: ',EqWord,' decimal = ');π WriteBitWord( EqWord );π WriteLn(' binary');π WriteLn;π ProcessEquipList;π WriteLn('Number of floppies installed: ', NumberFDD );π WriteLn('Math-coprocessor',Maybe(Is8087),'installed' );π WriteLn('PS/2 Mouse',Maybe(IsMouse),'installed' );π Write('Initial video mode: ',InitVMode,' (' );π Case InitVMode ofπ 0 : WriteLn('EGA, VGA, PGA)');π 1 : WriteLn('40x25 colour)');π 2 : WriteLn('80x25 colour)');π 3 : WriteLn('80x25 monochrome)');π end;π WriteLn('DMA support',Maybe(IsDMA),'installed' );π WriteLn('Number of COMs installed: ',COMcount );π WriteLn('Game port',Maybe(IsGame),'installed' );π WriteLn('IBM Luggable modem',Maybe(IsModem),'installed');π WriteLn('Number of Printer ports: ',LPTcount );πend {BitsNBytes}.π(*******************************************************************)ππ 2 05-28-9313:48ALL SWAG SUPPORT TEAM CLOCK1.PAS IMPORT 22 {πCARLOS BEGUIGNEπ}πProgram ClockOnScreen;ππ{$R-,V-,S-,M 1024, 0, 0ππ ClockOnScreen - Installs resident clock on upper right corner of screen.ππ{$IFOPT S+ }ππ{π You must disable stack checking here, since a Runtime error 202 willπ be generated whenever the stack Pointer (as returned by SPtr) is likelyπ to drop below 1024.π}πUsesπ Dos, Crt;πConstπ Offset = $8E; { Line 1, Column $8E/2 = 71 }π TimerTick = $1C; { Timer interrupt }π black = 0;π gray = 7;π EnvSeg = $002C; { Segment of Dos environment }π ColourSeg = $B800; { Segment of colour video RAM }π MonoSeg = $B000; { Segment of monochrome ideo RAM }π CrtSegment : Word = ColourSeg;ππTypeπ ScreenArray = Array[0..7] of Recordπ number, attribute : Char;π end;ππ ScreenPtr = ScreenArray;ππVarπ VideoMode : Byte Absolute $0000:$0449;π Screen : ^ScreenPtr; { Physical screen address }π ClockColour : Char;π Int1CSave : Procedure;ππProcedure ShowTime; Interrupt;πConstπ separator = ':';πVarπ ThisMode : Byte;π Time : LongInt;π i : Integer;π BIOSTicker : LongInt Absolute $0000:$046C;ππ Procedure DisplayDigit(offset : Integer; digit : Integer);π beginπ Screen^ [offset].number := Chr(digit div 10+Ord('0'));π Screen^ [offset+1].number := Chr(digit mod 10+Ord('0'));π end; { DisplayDigit }ππbeginπ ThisMode := VideoMode;π if not ((ThisMode = 2) or (ThisMode = 3) or (ThisMode = 7)) Thenπ Exit; { Do not popup in a Graphic mode }π For i := 0 to 7 Doπ Screen^[i].attribute := ClockColour;π Time := (1365*BIOSTicker) div 24852;π DisplayDigit(0, Time div 3600); { hours }π Screen^[2].number := separator;π Time := Time mod 3600;π DisplayDigit(3, Time div 60); { minutes }π Screen^[5].number := separator;π DisplayDigit(6, Time mod 60); { seconds }π Inline($9C); { PUSHF }π Int1CSave;πend; { ShowTime }ππProcedure Release(segment : Word);πInLine(π $07/ { POP ES ; get segment of block to release }π $B4/$49/ { MOV AH, 49h ; Free Allocated Memory }π $CD/$21); { INT 21h ; call Dos }ππbegin { ClockOnScreen }π if VideoMode = 7 Thenπ CrtSegment := MonoSeg;π ClockColour := Chr(gray*16+black); {display video attribute }π Screen := Ptr(CrtSegment, Offset);π GetIntVec(TimerTick, @Int1CSave);π SetIntVec(TimerTick, @ShowTime);π Release(MemW[PrefixSeg:EnvSeg]); {Release the environment }π Keep(0);π readln;πend. { ClockOnScreen }ππ 3 05-28-9313:48ALL SWAG SUPPORT TEAM INTREXAM.PAS IMPORT 7 Okay, well, For the most part, calling an interrupt from TP is fairlyπsimple. I'll use Interrupt 10h (service 0) as an example:ππProcedure CallInt;πVarπ Regs : Registers;πbeginπ Regs.AH := 0; { Specify service 0 }π Regs.AL := $13; { Mode number = 13 hex, MCGA 320x200x256 }π Intr($10,Regs); { Call the interrupt }πend;ππThis would shift the screen to the MCGA Graphics mode specified. Now,πit's easier to call this in BAsm (built-in Assembler):ππProcedure CallInt; Assembler;πAsmπ MOV AH,0 { Specify service 0 }π MOV AL,13h { Mode number = 13 hex, MCGA 320x200x256 }π inT 10h { Call the interrupt }πend;ππ 4 05-28-9313:48ALL SWAG SUPPORT TEAM ISRINFO.PAS IMPORT 6 {πSEAN PALMERππ> Does anyone know how to Write an ISR (interrupt service routine) that willπ> continue With the interrupt afterwards. EX: if you Write an ISR that trapsπ> the mouse Int 33h but let the mouse still operate.ππTry:π}ππVarπ oldMouseHook : Procedure;ππProcedure mouseHook(AX,BX,CX,DX,SI,DI,DS,ES,BP); interrupt;πbeginππ {Your stuff goes here}π {make sure it doesn't take TOO long!}ππ Asmπ pushF;π end; {simulate an interrupt}ππ oldMouseHook; {call old handler}πend;ππ{ to install: }ππ getIntVec($33,@oldMouseHook);π setIntVec($33,@mouseHook);ππ{ to deinstall: }ππ setIntVec($33,@oldMouseHook);ππ 5 05-28-9313:48ALL SWAG SUPPORT TEAM REG1.PAS IMPORT 6 π Registers DemoππPB> Procedure GetScreenType (Var SType: Char);πPB> VarπPB> Regs: Registers;πPB> beginπPB> Regs.AH := $0F;πPB> Intr($10, Regs);πPB> if Regs.AL = 7 thenπPB> sType := 'M'; <<<<<πPB> elseπPB> sType := 'C';πPB> end;ππ This Procedure would be ideal For a Function...π Function GetScreenType:Char;π ...π if Regs.AL=7 thenπ GetScreenType := 'M'π elseπ GetScreenType := 'C';π ...π